import execjs
import requests
import re
import ssl
import postframe_pb2
import response_pb2
import webcastChatMessage_pb2
import gzip
from websocket import WebSocketApp
from urllib.parse import urlencode

def get_id_str(room_id):
    cookies = {
        'ttwid': '1%7CYl75kmjPGttVcuK4DTOIw0Xd9kKU0-PiwbpCOdTld0k%7C1734685803%7C5fd664614ce827e7c49349441f231bd584cfa4f77211b2d27ee3d6b1f95b7266',
        'UIFID_TEMP': '26198ff38959f773c63a6fc9b3542e2fdcfd2f10d2782124ed1adc24709862dfaeedd94a97eb46d0b27ffc0b761ea0b930ee8f2df7260acf6a3d6661fc34360a5bc7c964d4c7d5e93250bc1d1180f645',
        'd_ticket': 'b7e7c6606772765f1d78cec1bc64d2b2e637b',
        'upgrade_tag': '1',
        'stream_recommend_feed_params': '%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1280%2C%5C%22screen_height%5C%22%3A720%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A8%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A150%7D%22',
        'strategyABtestKey': '%221741484400.155%22',
        'FORCE_LOGIN': '%7B%22videoConsumedRemainSeconds%22%3A180%7D',
        'passport_csrf_token': '2bf28be57feaf819815d7dfbce1e95d0',
        'passport_csrf_token_default': '2bf28be57feaf819815d7dfbce1e95d0',
        '__security_mc_1_s_sdk_crypt_sdk': '1dbdd586-4506-bbfe',
        'bd_ticket_guard_client_web_domain': '2',
        'passport_mfa_token': 'Cje5HzRPz9toY8bJW2iwz6PxLJiZTRR9zLzCaebRxt14saomwjVB%2BM8CbifZjwq1Y07CeT6DoSjLGkoKPIzR3UpDVlsl31kBDgnBNIpIHuE4zWKHw9zB4LRTZ9JCKNwu9pQx5LTQHZV8r2ugFlfb29kFPUN5%2FNMvlBDjw%2BsNGPax0WwgAiIBA5L2yYY%3D',
        'passport_assist_user': 'CkHdvesgN0ueaua5pWUTzWj9p47fbnLjRZxapYRKOCA2tEEy6AMjuY-wX4FEwUCsLQAzRD44XIbf6mBwwSj5TQcrNhpKCjyemKRJPtl4ra32pjLKFDVgTvjaOBefwYed-eAWcMftmXT_7k0rZZkU8ggtUg5kHk4AO1w-tJq922Z9Q6oQssLrDRiJr9ZUIAEiAQPpkNxK',
        'n_mh': 'HT-f1kVIvg_W6d6igo494q801j59-evEiYWCxH4vkHU',
        'sid_guard': 'fc38872fdc8879c9e6bf59d084d0c258%7C1741484553%7C5184000%7CThu%2C+08-May-2025+01%3A42%3A33+GMT',
        'uid_tt': '6e1b8b0ca06e1f07438f1c3ea2ed0915',
        'uid_tt_ss': '6e1b8b0ca06e1f07438f1c3ea2ed0915',
        'sid_tt': 'fc38872fdc8879c9e6bf59d084d0c258',
        'sessionid': 'fc38872fdc8879c9e6bf59d084d0c258',
        'sessionid_ss': 'fc38872fdc8879c9e6bf59d084d0c258',
        'is_staff_user': 'false',
        'sid_ucp_v1': '1.0.0-KGQxNzEzNjBhOTBhNDBkMDM0NjNjYjRhNDNhYWVlZDMzY2I5NjZhZWUKIQic0_C28cz8BxCJ5LO-BhjvMSAMMPzcxaMGOAdA9AdIBBoCaGwiIGZjMzg4NzJmZGM4ODc5YzllNmJmNTlkMDg0ZDBjMjU4',
        'ssid_ucp_v1': '1.0.0-KGQxNzEzNjBhOTBhNDBkMDM0NjNjYjRhNDNhYWVlZDMzY2I5NjZhZWUKIQic0_C28cz8BxCJ5LO-BhjvMSAMMPzcxaMGOAdA9AdIBBoCaGwiIGZjMzg4NzJmZGM4ODc5YzllNmJmNTlkMDg0ZDBjMjU4',
        'store-region': 'cn-gd',
        'store-region-src': 'uid',
        'login_time': '1741484455672',
        'SelfTabRedDotControl': '%5B%5D',
        'home_can_add_dy_2_desktop': '%221%22',
        '_bd_ticket_crypt_cookie': 'ba9e11644c2561fa891fc00514421bb6',
        '__security_mc_1_s_sdk_sign_data_key_web_protect': '19921070-4ef7-92b2',
        '__security_mc_1_s_sdk_cert_key': '6b245c1b-4a1c-88d6',
        '__security_server_data_status': '1',
        'publish_badge_show_info': '%220%2C0%2C0%2C1741484460779%22',
        'biz_trace_id': '20913c6a',
        'stream_player_status_params': '%22%7B%5C%22is_auto_play%5C%22%3A0%2C%5C%22is_full_screen%5C%22%3A0%2C%5C%22is_full_webscreen%5C%22%3A0%2C%5C%22is_mute%5C%22%3A1%2C%5C%22is_speed%5C%22%3A1%2C%5C%22is_visible%5C%22%3A0%7D%22',
        'x-web-secsdk-uid': '2dc866d2-52a2-4280-8c6a-f3541da69ada',
        'has_avx2': 'null',
        'device_web_cpu_core': '8',
        'device_web_memory_size': '8',
        'live_use_vvc': '%22false%22',
        'csrf_session_id': '67b8bce0ef32a165ec8460bcb534d97b',
        'fpk1': 'U2FsdGVkX1+lx9MDak7+p78HiAcyVw0NAyDSimcnIVbasPaOWl9TwELCl7xfrnhg6F+Nw0ZGeL3xmiJWh6g58w==',
        'fpk2': '800683566637788f812c9cb58711ba4c',
        'xgplayer_device_id': '67581487532',
        'xgplayer_user_id': '980641383027',
        'volume_info': '%7B%22isUserMute%22%3Atrue%2C%22isMute%22%3Atrue%2C%22volume%22%3A0.6%7D',
        '__ac_nonce': '067cd5276004ca52b11b3',
        '__ac_signature': '_02B4Z6wo00f01C2jz-QAAIDAGocLuJDfGjQtg8tAAGyscf',
        'download_guide': '%223%2F20250309%2F0%22',
        'webcast_local_quality': 'origin',
        '__live_version__': '%221.1.2.8804%22',
        'xg_device_score': '7.541509673083398',
        'odin_tt': '64677690d393d79476b54f8754b72fcc97c7d4722e93fc661093cd1523b34f8474656b09933e43b6a2d0b1d7b76fe68ba31c7f1a8e5d2881feba1d08274f80c9',
        'bd_ticket_guard_client_data': 'eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCUDZDeWVJZEhaNlRYOGFDbC9SaUs2M05mZmIzckEzcE5WVFFCYWlEU3dIQkFoVnN0UjVqQlNRMVJrQWl1dGtvbFZaRHRIY3BtREloelY0Q05VbStnR0U9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D',
        'WallpaperGuide': '%7B%22showTime%22%3A1741484500925%2C%22closeTime%22%3A0%2C%22showCount%22%3A1%2C%22cursor1%22%3A41%2C%22cursor2%22%3A12%7D',
        'live_can_add_dy_2_desktop': '%220%22',
        'IsDouyinActive': 'false',
        'passport_fe_beating_status': 'false',
    }

    headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'cache-control': 'no-cache',
        'pragma': 'no-cache',
        'priority': 'u=0, i',
        'referer': 'https://live.douyin.com/',
        'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-site': 'same-origin',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0',
        'cookie': 'ttwid=1%7CYl75kmjPGttVcuK4DTOIw0Xd9kKU0-PiwbpCOdTld0k%7C1734685803%7C5fd664614ce827e7c49349441f231bd584cfa4f77211b2d27ee3d6b1f95b7266; UIFID_TEMP=26198ff38959f773c63a6fc9b3542e2fdcfd2f10d2782124ed1adc24709862dfaeedd94a97eb46d0b27ffc0b761ea0b930ee8f2df7260acf6a3d6661fc34360a5bc7c964d4c7d5e93250bc1d1180f645; d_ticket=b7e7c6606772765f1d78cec1bc64d2b2e637b; upgrade_tag=1; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1280%2C%5C%22screen_height%5C%22%3A720%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A8%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A150%7D%22; strategyABtestKey=%221741484400.155%22; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%7D; passport_csrf_token=2bf28be57feaf819815d7dfbce1e95d0; passport_csrf_token_default=2bf28be57feaf819815d7dfbce1e95d0; __security_mc_1_s_sdk_crypt_sdk=1dbdd586-4506-bbfe; bd_ticket_guard_client_web_domain=2; passport_mfa_token=Cje5HzRPz9toY8bJW2iwz6PxLJiZTRR9zLzCaebRxt14saomwjVB%2BM8CbifZjwq1Y07CeT6DoSjLGkoKPIzR3UpDVlsl31kBDgnBNIpIHuE4zWKHw9zB4LRTZ9JCKNwu9pQx5LTQHZV8r2ugFlfb29kFPUN5%2FNMvlBDjw%2BsNGPax0WwgAiIBA5L2yYY%3D; passport_assist_user=CkHdvesgN0ueaua5pWUTzWj9p47fbnLjRZxapYRKOCA2tEEy6AMjuY-wX4FEwUCsLQAzRD44XIbf6mBwwSj5TQcrNhpKCjyemKRJPtl4ra32pjLKFDVgTvjaOBefwYed-eAWcMftmXT_7k0rZZkU8ggtUg5kHk4AO1w-tJq922Z9Q6oQssLrDRiJr9ZUIAEiAQPpkNxK; n_mh=HT-f1kVIvg_W6d6igo494q801j59-evEiYWCxH4vkHU; sid_guard=fc38872fdc8879c9e6bf59d084d0c258%7C1741484553%7C5184000%7CThu%2C+08-May-2025+01%3A42%3A33+GMT; uid_tt=6e1b8b0ca06e1f07438f1c3ea2ed0915; uid_tt_ss=6e1b8b0ca06e1f07438f1c3ea2ed0915; sid_tt=fc38872fdc8879c9e6bf59d084d0c258; sessionid=fc38872fdc8879c9e6bf59d084d0c258; sessionid_ss=fc38872fdc8879c9e6bf59d084d0c258; is_staff_user=false; sid_ucp_v1=1.0.0-KGQxNzEzNjBhOTBhNDBkMDM0NjNjYjRhNDNhYWVlZDMzY2I5NjZhZWUKIQic0_C28cz8BxCJ5LO-BhjvMSAMMPzcxaMGOAdA9AdIBBoCaGwiIGZjMzg4NzJmZGM4ODc5YzllNmJmNTlkMDg0ZDBjMjU4; ssid_ucp_v1=1.0.0-KGQxNzEzNjBhOTBhNDBkMDM0NjNjYjRhNDNhYWVlZDMzY2I5NjZhZWUKIQic0_C28cz8BxCJ5LO-BhjvMSAMMPzcxaMGOAdA9AdIBBoCaGwiIGZjMzg4NzJmZGM4ODc5YzllNmJmNTlkMDg0ZDBjMjU4; store-region=cn-gd; store-region-src=uid; login_time=1741484455672; SelfTabRedDotControl=%5B%5D; home_can_add_dy_2_desktop=%221%22; _bd_ticket_crypt_cookie=ba9e11644c2561fa891fc00514421bb6; __security_mc_1_s_sdk_sign_data_key_web_protect=19921070-4ef7-92b2; __security_mc_1_s_sdk_cert_key=6b245c1b-4a1c-88d6; __security_server_data_status=1; publish_badge_show_info=%220%2C0%2C0%2C1741484460779%22; biz_trace_id=20913c6a; stream_player_status_params=%22%7B%5C%22is_auto_play%5C%22%3A0%2C%5C%22is_full_screen%5C%22%3A0%2C%5C%22is_full_webscreen%5C%22%3A0%2C%5C%22is_mute%5C%22%3A1%2C%5C%22is_speed%5C%22%3A1%2C%5C%22is_visible%5C%22%3A0%7D%22; x-web-secsdk-uid=2dc866d2-52a2-4280-8c6a-f3541da69ada; has_avx2=null; device_web_cpu_core=8; device_web_memory_size=8; live_use_vvc=%22false%22; csrf_session_id=67b8bce0ef32a165ec8460bcb534d97b; fpk1=U2FsdGVkX1+lx9MDak7+p78HiAcyVw0NAyDSimcnIVbasPaOWl9TwELCl7xfrnhg6F+Nw0ZGeL3xmiJWh6g58w==; fpk2=800683566637788f812c9cb58711ba4c; xgplayer_device_id=67581487532; xgplayer_user_id=980641383027; volume_info=%7B%22isUserMute%22%3Atrue%2C%22isMute%22%3Atrue%2C%22volume%22%3A0.6%7D; __ac_nonce=067cd5276004ca52b11b3; __ac_signature=_02B4Z6wo00f01C2jz-QAAIDAGocLuJDfGjQtg8tAAGyscf; download_guide=%223%2F20250309%2F0%22; webcast_local_quality=origin; __live_version__=%221.1.2.8804%22; xg_device_score=7.541509673083398; odin_tt=64677690d393d79476b54f8754b72fcc97c7d4722e93fc661093cd1523b34f8474656b09933e43b6a2d0b1d7b76fe68ba31c7f1a8e5d2881feba1d08274f80c9; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCUDZDeWVJZEhaNlRYOGFDbC9SaUs2M05mZmIzckEzcE5WVFFCYWlEU3dIQkFoVnN0UjVqQlNRMVJrQWl1dGtvbFZaRHRIY3BtREloelY0Q05VbStnR0U9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D; WallpaperGuide=%7B%22showTime%22%3A1741484500925%2C%22closeTime%22%3A0%2C%22showCount%22%3A1%2C%22cursor1%22%3A41%2C%22cursor2%22%3A12%7D; live_can_add_dy_2_desktop=%220%22; IsDouyinActive=false; passport_fe_beating_status=false',
    }

    response = requests.get(f'https://live.douyin.com/{room_id}', cookies=cookies, headers=headers)

    match = re.search(r'"id_str\\":\\"(\d+)\\"', response.text)

    # print(response.text)
    if match:
        # 提取的数字部分
        id_str = match.group(1)
        return {
            "id_str": id_str,
            "tt_wid": response.cookies.get_dict()["ttwid"]
        }
    else:
        return ''

def main():
    roomId = '436350920696'
    # params = {
    #     "app_name": "douyin_web",
    #     "version_code": "180800",
    #     "webcast_sdk_version": "1.0.14-beta.0",
    #     "update_version_code": "1.0.14-beta.0",
    #     "compress": "gzip",
    #     "device_platform": "web",
    #     "cookie_enabled": True,
    #     "screen_width": 1280,
    #     "screen_height": 720,
    #     "browser_language": "zh-CN",
    #     "browser_platform": "Win32",
    #     "browser_name": "Mozilla",
    #     "browser_version": "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0",
    #     "browser_online": True,
    #     "tz_name": "Etc/GMT-8",
    #     "cursor": "t-1741510140850_r-1_d-1_u-1_h-7479728990720578610",
    #     "internal_ext": "internal_src:dim|wss_push_room_id:7479924158589717283|wss_push_did:7450418716460402202|first_req_ms:1741568724940|fetch_time:1741568725025|seq:1|wss_info:0-1741568725025-0-0|wrds_v:7479980709021492061",
    #     "host": "https://live.douyin.com",
    #     "aid": 6383,
    #     "live_id": 1,
    #     "did_rule": 3,
    #     "endpoint": "live_pc",
    #     "support_wrds": 1,
    #     "user_unique_id": "7450418716460402202",
    #     "im_path": "/webcast/im/fetch/",
    #     "identity": "audience",
    #     "need_persist_msg_count": 15,
    #     "insert_task_id": '',
    #     "live_reason": '',
    #     "room_id": "7479721882401917735",
    #     "heartbeatDuration": 0,
    #     "signature": "f4ecWfGv90vTDLKV"
    # }
    resDic = get_id_str(roomId)
    # params["room_id"] = resDic.get("id_str")
    sign = execjs.compile(open("index.js", encoding='utf-8').read()).call("get_sign", resDic.get("id_str"))
    # params["signature"] = sign
    base_uri = "wss://webcast5-ws-web-hl.douyin.com/webcast/im/push/v2/"
    # query_string = urlencode(params)
    # 构造完整的 WebSocket URL
    # uri = f"{base_uri}?{query_string}"
    uri = f"wss://webcast5-ws-web-lf.douyin.com/webcast/im/push/v2/?app_name=douyin_web&version_code=180800&webcast_sdk_version=1.0.14-beta.0&update_version_code=1.0.14-beta.0&compress=gzip&device_platform=web&cookie_enabled=true&screen_width=1280&screen_height=720&browser_language=zh-CN&browser_platform=Win32&browser_name=Mozilla&browser_version=5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/134.0.0.0%20Safari/537.36%20Edg/134.0.0.0&browser_online=true&tz_name=Etc/GMT-8&cursor=fh-7480106147005944867_t-1741598038646_r-1_d-1_u-1&internal_ext=internal_src:dim|wss_push_room_id:7480101225355103028|wss_push_did:7450418716460402202|first_req_ms:1741598038526|fetch_time:1741598038646|seq:1|wss_info:0-1741598038646-0-0|wrds_v:7480106615987771075&host=https://live.douyin.com&aid=6383&live_id=1&did_rule=3&endpoint=live_pc&support_wrds=1&user_unique_id=7450418716460402202&im_path=/webcast/im/fetch/&identity=audience&need_persist_msg_count=15&insert_task_id=&live_reason=&room_id={resDic.get('id_str')}&heartbeatDuration=0&signature={sign}"
    testUri = "wss://webcast5-ws-web-lf.douyin.com/webcast/im/push/v2/?app_name=douyin_web&version_code=180800&webcast_sdk_version=1.0.14-beta.0&update_version_code=1.0.14-beta.0&compress=gzip&device_platform=web&cookie_enabled=true&screen_width=1280&screen_height=720&browser_language=zh-CN&browser_platform=Win32&browser_name=Mozilla&browser_version=5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/134.0.0.0%20Safari/537.36%20Edg/134.0.0.0&browser_online=true&tz_name=Etc/GMT-8&cursor=fh-7480106147005944867_t-1741598038646_r-1_d-1_u-1&internal_ext=internal_src:dim|wss_push_room_id:7480101225355103028|wss_push_did:7450418716460402202|first_req_ms:1741598038526|fetch_time:1741598038646|seq:1|wss_info:0-1741598038646-0-0|wrds_v:7480106615987771075&host=https://live.douyin.com&aid=6383&live_id=1&did_rule=3&endpoint=live_pc&support_wrds=1&user_unique_id=7450418716460402202&im_path=/webcast/im/fetch/&identity=audience&need_persist_msg_count=15&insert_task_id=&live_reason=&room_id=7480101225355103028&heartbeatDuration=0&signature=fh4NBaHfhDvuXWLc"
    # ssl_context = ssl.SSLContext()
    # ssl_context.verify_mode = ssl.CERT_NONE  # 禁用证书验证
    ws = WebSocketApp(
        url=uri,
        header={
            'Origin': 'https://live.douyin.com',
            'Cache-Control': 'no-cache',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0',
        },
        cookie=f"ttwid={resDic.get('tt_wid')}",
        on_open=on_open,
        on_message=on_message,
        on_error=on_error,
        on_close=on_close
    )
    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}, ping_interval=10, ping_timeout=5)

def on_open(ws):
    print("on_open", ws)
def on_message(ws, message):
    #回调函数，直接收到抖音的弹幕信息
    pushframe = postframe_pb2.PushFrame()
    pushframe.ParseFromString(message)

    responsePb2 =  response_pb2.Response()
    pushframePL = gzip.decompress(pushframe.payload)
    responsePb2.ParseFromString(pushframePL)

    # print("on_message:::pushframe", responsePb2)
    for message in responsePb2.messages:
        if message.method == "WebcastChatMessage":
            webcastChatMessage = webcastChatMessage_pb2.ChatMessage()
            webcastChatMessage.ParseFromString(message.payload)
            print("on_message:::webcastChatMessage", webcastChatMessage)
def on_error(ws, message):
    print("on_open", ws, message)
def on_close(ws, *args, **kwargs):
    pass

# 运行异步函数

if __name__ =='__main__':
    main()